#include "bsp_usart.h"
 
static USARTInstance* USART_Instance_List[USART_MAX_NUM] = {NULL};
static uint8_t Idx = 0;

USARTInstance* USARTInit(USART_Init_Config_s* _config)
{
    USARTInstance* instance = (USARTInstance*)malloc(sizeof(USARTInstance));
    memset(instance, 0, sizeof(USARTInstance));

    instance -> USARTx = _config -> USARTx;
    instance -> recv_buff_size = _config -> recv_buff_size;
    instance -> usart_callback = _config -> usart_callback;
    instance -> id = _config -> id;
    USART_Instance_List[Idx ++] = instance;
    return instance;
}

void USARTSend(USARTInstance* _instance, uint8_t* data, 
               uint16_t size, USART_TRANSFER_MODE_e mode)
{
    switch (mode)
    {
        case USART_TRANSFER_BLOCKING:
            HAL_UART_Transmit(_instance -> USARTx, data, size, 100);
            break;
        case USART_TRANSFER_IT:
            HAL_UART_Transmit_IT(_instance -> USARTx, data, size);
            break;
        case USART_TRANSFER_DMA:
            HAL_UART_Transmit_DMA(_instance -> USARTx, data, size);
            break;
        default:
            // error mode !! check it !!
            while(1)
                ;
            break;
    }
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
{
    for (uint8_t i = 0; i < Idx; i ++)
    {
        if (huart == USART_Instance_List[i] -> USARTx)
        {
            if(NULL != USART_Instance_List[i] -> usart_callback)
            {
                USART_Instance_List[i] -> usart_callback();
                memset(USART_Instance_List[i] -> recv_buff, 0, Size);
            }
            HAL_UARTEx_ReceiveToIdle_DMA(USART_Instance_List[i] -> USARTx,
                                         USART_Instance_List[i] -> recv_buff,
                                         USART_Instance_List[i] -> recv_buff_size);
            __HAL_DMA_DISABLE_IT(USART_Instance_List[i] -> USARTx -> hdmarx, DMA_IT_HT);
            return;
        }   
    }
}
